#include "wav_recoder.h"
#include "format_wav.h"
#include "audio_es7210.h"
#include <esp_timer.h>
#include <esp_check.h>

#define TAG "WavRecoder"

WavRecoder::WavRecoder(std::shared_ptr<FileInterface> FileInterface, 
                        std::shared_ptr<AudioInputInterface> AudioInputInterface)
            : m_file(FileInterface)
            , m_audio_input(AudioInputInterface)
{

}

esp_err_t WavRecoder::record(uint16_t seconds)
{
    esp_err_t ret = ESP_OK;

    // 计算音频数据大小
    uint32_t byte_rate = EXAMPLE_I2S_SAMPLE_RATE * EXAMPLE_I2S_CHAN_NUM * EXAMPLE_I2S_SAMPLE_BITS / 8;
    uint32_t wav_size = byte_rate * seconds;

    // 创建初始wav文件头部（数据大小暂时设为0）
    wav_header_t wav_header = WAV_HEADER_PCM_DEFAULT(wav_size, EXAMPLE_I2S_SAMPLE_BITS, 
                                                    EXAMPLE_I2S_SAMPLE_RATE, EXAMPLE_I2S_CHAN_NUM);

    // 1、写入wav文件头部
    if (m_file->write_file((char *)&wav_header, sizeof(wav_header_t)) != ESP_OK)
    {
        ESP_LOGE(TAG, "write wav header failed");
        return ESP_FAIL;
    }

    // 2、实施录音并分段写入数据
    size_t wav_written = 0;
    static int16_t i2s_readraw_buf[EXAMPLE_I2S_BUF_LEN];

    // 使能通道，如果出错直接跳到err标签位置
    ESP_GOTO_ON_ERROR(m_audio_input->enable(), err, TAG, "ERROR: while starting i2s rx channel");

    while (wav_written < wav_size)
    {
        if (wav_written % byte_rate < sizeof(i2s_readraw_buf))
        {
            ESP_LOGI(TAG, "Recording: %"PRIu32"/%ds", wav_written/byte_rate + 1, EXAMPLE_RECORD_TIME_SECS);
            printf(".");
        }

        size_t bytes_read = 0;
        /* Read raw data from es7210 */
        ESP_GOTO_ON_ERROR(m_audio_input->read(i2s_readraw_buf, sizeof(i2s_readraw_buf), &bytes_read), 
                                err, TAG, "ERROR: while reading samples from i2s");

        /* Write the samples to the WAV file */
        // ESP_GOTO_ON_FALSE(m_file->write_file(filename, (char *)i2s_readraw_buf, true), 
        //                         ESP_FAIL, err, TAG, "ERROR: while writing samples to WAV file");

        if (m_file->write_file((char *)i2s_readraw_buf, bytes_read)!= ESP_OK)
        {
            ESP_LOGE(TAG, "write wav data failed");
            goto err;
        }
        
        wav_written += bytes_read;
        
    }

    printf("录制完成\n");

err:
    m_audio_input->disable();
    return ret;
}